package com.party.admin.biz.asynexport;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.admin.biz.crowdfund.ProjectBizService;
import com.party.admin.biz.crowdfund.RepresentBizService;
import com.party.admin.redisPubSub.publish.RedisMsgPublish;
import com.party.admin.redisPubSub.subscribe.SubScribeMessage;
import com.party.admin.utils.RealmUtils;
import com.party.admin.web.dto.output.crowdfund.ListForTargetOutput;
import com.party.admin.web.dto.output.crowdfund.ProjectForActivityOutput;
import com.party.common.constant.Constant;
import com.party.common.redis.StringJedis;
import com.party.common.utils.DateUtils;
import com.party.common.utils.FileUtils;
import com.party.core.model.activity.Activity;
import com.party.core.model.distributor.WithCount;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.picCloud.CosCloudBizService;
import com.party.file.cos.dto.UploadResult;
import com.party.file.cos.meta.InsertOnly;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 联合发起数据异步导出
 * Created by wei.li
 *
 * @date 2017/7/19 0019
 * @time 14:33
 */
@Service
@Component(value = "representAsynExportService")
public class RepresentAsynExportService implements IAsynExportService {

    private Integer target = 0;

    private String targetId = null;

    private String uploadPath = Constant.UPLOAD_ZIP;

    @Autowired
    private ProjectBizService projectBizService;

    @Autowired
    private AsynExportBizService asynExportBizService;

    @Autowired
    private IActivityService activityService;

    @Autowired
    private StringJedis stringJedis;

    @Autowired
    private RepresentBizService representBizService;

    @Autowired
    private CosCloudBizService cosCloudBizService;

    @Autowired
    private RedisMsgPublish redisMsgPublish;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 批量导出
     *
     * @param id 联合发起编号
     */
    @Override
    public <T> void export(String id, T t, String sessionId) {
        Activity activity = activityService.get(id);
        try {
            String path = id + "_dy";
            targetId = id;
            WithCount withCount = (WithCount) t;
            List<ListForTargetOutput> listForTargetOutputList = representBizService.listForTarget(null, withCount, id);
            target = listForTargetOutputList.size() + 1;

            IAsynExportService asynExportService = new RepresentAsynExportService();

            ExecutorService threadPool = Executors.newFixedThreadPool(30);

            for (ListForTargetOutput output : listForTargetOutputList) {
                threadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        //导出
                        List<ProjectForActivityOutput> list = projectBizService.listForDistributorId(output.getId(), null);
                        String newFilePath = Constant.replaceDirSpecial(output.getAuthorName()).replaceAll(" ", "");
                        String realPath = asynExportBizService.getBaseDir() + Constant.BATCH + Constant.EXCEL_URL + path + "/" + newFilePath
                                + DateUtils.formatNowToYMDHMS() + new Random().nextInt(99999) + "/";
                        String fileName = DateUtils.formatNowToYMDHMS() + ".xlsx";
                        asynExportBizService.export(fileName, ProjectForActivityOutput.class, list, realPath, asynExportService, null, false);
                    }
                });
            }
            threadPool.shutdown();

            while (true) {
                if (threadPool.isTerminated()) {
                    System.out.println("所有的子线程都结束了！");
                    break;
                }
            }

            asynExportBizService.export2(Constant.replaceDirSpecial(activity.getTitle()) + "联合发起的.xlsx", ListForTargetOutput.class,
                    listForTargetOutputList, asynExportBizService.getBaseDir() + Constant.BATCH + Constant.EXCEL_URL + path + "/", this, null, true);
            Map<String, String> json = Maps.newHashMap();
            json.put("memberId", RealmUtils.getCurrentUser().getId());
            json.put("sessionId", sessionId);
            json.put("message", "\"" + activity.getTitle() + "\"联合发起人员导出成功了");
            String param = JSONUtils.toJSONString(json);
            redisMsgPublish.publish(SubScribeMessage.CROWDFUND_EXPORT_CHANNEL_NAME, param);
        } catch (Exception e) {
            logger.error("导出异常", e);
            Map<String, String> json = Maps.newHashMap();
            json.put("memberId", RealmUtils.getCurrentUser().getId());
            json.put("sessionId", sessionId);
            json.put("message", "\"" + activity.getTitle() + "\"联合发起人员导出异常了");
            String param = JSONUtils.toJSONString(json);
            redisMsgPublish.publish(SubScribeMessage.CROWDFUND_EXPORT_CHANNEL_NAME, param);
        }
    }


    /**
     * 导出回调
     *
     * @param result 导出结果
     */
    @Override
    public synchronized void callBack(Boolean result, String fileName1, boolean isEnd){
        if (isEnd) {
            String targetUrl = asynExportBizService.getBaseDir() + Constant.BATCH + Constant.EXCEL_URL + targetId + "_dy";
            String fileName = "dy_" + targetId + ".zip";
            String cloudFilePath = String.format(uploadPath, fileName);
            try {
                InputStream inputStream = FileUtils.zipFiles(targetUrl, "*");
                UploadResult uploadResult
                        = cosCloudBizService.uploadFile(inputStream, cloudFilePath, InsertOnly.OVER_WRITE);
                String sourceUrl = uploadResult.getSourceUrl();
                Map<String,Object> map = Maps.newHashMap();
                map.put("sourceUrl", sourceUrl);
                map.put("uploadTime", DateUtils.formatDate(new Date(), DateUtils.DATETIME_PATTERN));

                //设置24小时过期
                stringJedis.setValue(Constant.PRE_ZIP_URL + "represent" + targetId, JSONObject.toJSONString(map));
                FileUtils.deleteDirectory(asynExportBizService.getBaseDir() + Constant.BATCH + Constant.EXCEL_URL + targetId + "_dy");
            } catch (Exception e) {
                logger.error("代言上传压缩文件异常", e);
            }
        }
    }

    @Override
    public <T> void exportDPData(String id, T t, String sessionId) {
    }

    @Override
    public <T> void exportTransferData(String id, T t, String sessionId) {

    }

    @Override
    public <T> void exportMultipleProject(String id, T t, String sessionId) {

    }

    @Override
    public void callBack(Boolean result, String fileName, boolean isEnd, String cloudName) {

    }
}